<template>
  <div class="products-admin">
    <!-- 内容区域 -->
    <div class="content">
      <div class="content-header">
        <h2>积分商城 - 商品管理</h2>
        <button class="add-btn" @click="showAddDialog = true">+ 添加商品</button>
      </div>

      <!-- 搜索和筛选区域 -->
      <div class="filter-section">
        <div class="filter-group">
          <input
              v-model="searchKeyword"
              type="text"
              placeholder="搜索商品名称"
              class="search-input"
              @keyup.enter="loadProducts"
          >
          <select v-model="searchTypeId" class="filter-select">
            <option value="">所有分类</option>
            <option v-for="type in productTypes" :key="type.typeId" :value="type.typeId">
              {{ type.name }}
            </option>
          </select>
          <button class="search-btn" @click="loadProducts">搜索</button>
        </div>
      </div>

      <!-- 商品表格 -->
      <div class="table-container">
        <table class="products-table">
          <thead>
          <tr>
            <th>ID</th>
            <th>图片</th>
            <th>商品名称</th>
            <th>商品分类</th>
            <th>所需积分</th>
            <th>库存</th>
            <th>状态</th>
            <th>创建时间</th>
            <th>操作</th>
          </tr>
          </thead>
          <tbody>
          <tr v-for="product in products" :key="product.productId">
            <td>{{ product.productId }}</td>
            <td>
              <div class="product-image">
                <img v-if="product.images && JSON.parse(product.images).length > 0"
                     :src="JSON.parse(product.images)[0]"
                     alt="商品图片"
                     @error="handleImageError">
                <span v-else class="image-placeholder">🛍️</span>
              </div>
            </td>
            <td>{{ product.name }}</td>
            <td>{{ getCategoryName(product.typeId) }}</td>
            <td>{{ product.pointsPrice }}</td>
            <td>{{ product.stock }}</td>
            <td>
                <span :class="['status', product.status === 1 ? 'status-on' : 'status-off']">
                  {{ product.status === 1 ? '上架' : '下架' }}
                </span>
            </td>
            <td>{{ formatDate(product.createdAt) }}</td>
            <td>
              <div class="action-buttons">
                <button class="btn-edit" @click="editProduct(product)">编辑</button>
                <button v-if="product.status === 1" class="btn-off" @click="updateProductStatus(product.productId, 2)">
                  下架
                </button>
                <button v-else class="btn-on" @click="updateProductStatus(product.productId, 1)">
                  上架
                </button>
                <button class="btn-delete" @click="deleteProduct(product.productId)">删除</button>
              </div>
            </td>
          </tr>
          </tbody>
        </table>
      </div>

      <!-- 分页控件 -->
      <div class="pagination">
        <button @click="prevPage" :disabled="currentPage === 1">上一页</button>
        <span>第 {{ currentPage }} 页 / 共 {{ totalPages }} 页</span>
        <button @click="nextPage" :disabled="currentPage === totalPages">下一页</button>
      </div>
    </div>

    <!-- 添加/编辑商品对话框 -->
    <div v-if="showAddDialog" class="modal-overlay">
      <div class="modal">
        <div class="modal-header">
          <h3>{{ isEditing ? '编辑商品' : '添加商品' }}</h3>
          <button class="close-btn" @click="closeDialog">×</button>
        </div>

        <div class="modal-content">
          <div class="form-group">
            <label>商品名称</label>
            <input v-model="currentProduct.name" type="text" placeholder="请输入商品名称">
          </div>
          <div class="form-group">
            <label>商品分类</label>
            <select v-model="currentProduct.typeId" class="category-select">
              <option v-for="type in productTypes" :key="type.typeId" :value="type.typeId">
                {{ type.name }}
              </option>
            </select>
          </div>
          <div class="form-group">
            <label>商品描述</label>
            <textarea v-model="currentProduct.description" placeholder="请输入商品描述"></textarea>
          </div>
          <div class="form-group">
            <label>商品图片</label>
            <input type="file" ref="fileInput" @change="handleFileUpload" accept="image/*" multiple>
            <div v-if="uploadProgress > 0" class="upload-progress">
              <div class="progress-bar" :style="{ width: uploadProgress + '%' }"></div>
              <span>{{ uploadProgress }}%</span>
            </div>
            <div v-if="uploadedImageUrls.length > 0" class="uploaded-images">
              <div v-for="(url, index) in uploadedImageUrls" :key="index" class="image-preview">
                <img :src="url" alt="商品图片" @error="handleImageError">
                <button @click="removeImage(index)" class="remove-image-btn">×</button>
              </div>
            </div>
          </div>
          <div class="form-group">
            <label>所需积分</label>
            <input v-model="currentProduct.pointsPrice" type="number" placeholder="请输入所需积分" min="0">
          </div>
          <div class="form-group">
            <label>库存数量</label>
            <input v-model="currentProduct.stock" type="number" placeholder="请输入库存数量" min="0">
          </div>
          <div class="form-group">
            <label>状态</label>
            <select v-model="currentProduct.status">
              <option :value="1">上架</option>
              <option :value="2">下架</option>
            </select>
          </div>
        </div>

        <div class="modal-footer">
          <button class="btn-cancel" @click="closeDialog">取消</button>
          <button class="btn-confirm" @click="saveProduct" :disabled="isSaving">
            {{ isSaving ? '保存中...' : '保存' }}
          </button>
        </div>
      </div>
    </div>

    <!-- 删除确认对话框 -->
    <div v-if="showDeleteConfirm" class="modal-overlay">
      <div class="modal">
        <h3>确认删除</h3>
        <p>确定要删除该商品吗？此操作不可恢复。</p>
        <div class="modal-actions">
          <button class="btn-cancel" @click="showDeleteConfirm = false">取消</button>
          <button class="btn-confirm" @click="confirmDelete">确认删除</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import axios from '../utils/axios.ts';
import OSS from 'ali-oss';

export default {
  name: 'ProductsAdmin',
  data() {
    return {
      products: [],
      productTypes: [],
      showAddDialog: false,
      showDeleteConfirm: false,
      isEditing: false,
      isSaving: false,
      uploadProgress: 0,
      uploadedImageUrls: [],
      currentProduct: this.getDefaultProduct(),
      productToDelete: null,
      searchKeyword: '',
      searchTypeId: '',
      currentPage: 1,
      pageSize: 10,
      totalPages: 1
    };
  },
  mounted() {
    this.loadProducts();
    this.loadProductTypes();
  },
  methods: {
    getDefaultProduct() {
      return {
        productId: null,
        name: '',
        typeId: 1,
        description: '',
        pointsPrice: 0,
        stock: 0,
        status: 1,
        images: '[]'
      };
    },
    async loadProducts() {
      try {
        const params = {
          page: this.currentPage,
          size: this.pageSize
        };

        if (this.searchKeyword) {
          params.keyword = this.searchKeyword;
        }

        if (this.searchTypeId) {
          params.typeId = this.searchTypeId;
        }

        const response = await axios.get('/api/mallProducts/list', { params });
        console.log(response.data)
        if (response.code === 200) {
          this.products = response.data.records || response.data;
          this.totalPages = response.data.pages || Math.ceil(response.data.total / this.pageSize);
        } else {
          console.error('获取商品列表失败:', response.msg);
        }
      } catch (error) {
        console.error('获取商品列表失败:', error);
      }
    },
    async loadProductTypes() {
      try {
        const response = await axios.get('/api/mallProductTypes/list');
        if (response.code === 200) {
          this.productTypes = response.data.records || response.data;
        }
      } catch (error) {
        console.error('获取商品分类失败:', error);
      }
    },
    getCategoryName(typeId) {
      const type = this.productTypes.find(t => t.typeId === typeId);
      return type ? type.name : '未知分类';
    },
    formatDate(date) {
      if (!date) return '';
      const d = new Date(date);
      return `${d.getFullYear()}/${(d.getMonth() + 1).toString().padStart(2, '0')}/${d.getDate().toString().padStart(2, '0')}`;
    },
    editProduct(product) {
      this.isEditing = true;
      this.currentProduct = { ...product };
      this.uploadedImageUrls = product.images ? JSON.parse(product.images) : [];
      this.showAddDialog = true;
    },
    closeDialog() {
      this.showAddDialog = false;
      this.isEditing = false;
      this.currentProduct = this.getDefaultProduct();
      this.uploadedImageUrls = [];
      this.uploadProgress = 0;
      if (this.$refs.fileInput) {
        this.$refs.fileInput.value = '';
      }
    },
    async handleFileUpload(event) {
      const files = event.target.files;
      if (!files || files.length === 0) return;

      this.uploadProgress = 10;

      try {
        for (let i = 0; i < files.length; i++) {
          const file = files[i];

          if (!file.type.match('image.*')) {
            alert('请选择图片文件');
            continue;
          }

          if (file.size > 5 * 1024 * 1024) {
            alert('图片大小不能超过5MB');
            continue;
          }

          try {
            this.uploadProgress = 30;

            const client = new OSS({
              endpoint: 'oss-cn-hangzhou.aliyuncs.com',
              accessKeyId: 'LTAI5tJQmVkAX4LzgqYwdUFN',
              accessKeySecret: '2f26fXcpc1utxlR0hSbvbJRbeIf4hE',
              bucket: 'yangodofsc',
            });

            const fileName = `images/${Date.now()}_${file.name}`;

            const result = await client.put(fileName, file, {
              progress: (p) => {
                this.uploadProgress = Math.round(p * 100);
              }
            });

            this.uploadedImageUrls = [...this.uploadedImageUrls, result.url];
            this.uploadProgress = 100;

          } catch (error) {
            console.error('上传失败:', error);
            alert('图片上传失败');
          }
        }

        setTimeout(() => {
          this.uploadProgress = 0;
        }, 1000);

      } catch (error) {
        console.error('上传处理失败:', error);
        this.uploadProgress = 0;
      }
    },
    handleImageError(event) {
      console.error('图片加载失败:', event);
      event.target.style.display = 'none';
    },
    removeImage(index) {
      this.uploadedImageUrls.splice(index, 1);
      this.uploadedImageUrls = [...this.uploadedImageUrls];
    },
    async updateProductStatus(productId, status) {
      try {
        const response = await axios.put(`/api/mallProducts/updateStatus/${productId}`, null, {
          params: { status }
        });

        if (response.code === 200) {
          alert('商品状态更新成功');
          this.loadProducts();
        } else {
          alert('状态更新失败: ' + response.msg);
        }
      } catch (error) {
        console.error('更新商品状态失败:', error);
        alert('状态更新失败');
      }
    },
    deleteProduct(productId) {
      this.productToDelete = productId;
      this.showDeleteConfirm = true;
    },
    async confirmDelete() {
      if (!this.productToDelete) return;

      try {
        const response = await axios.delete(`/api/mallProducts/delete/${this.productToDelete}`);

        if (response && response.code === 200) {
          alert('商品删除成功');
          await this.loadProducts();
        } else {
          alert('删除失败: ' + (response.data?.msg || '未知错误'));
        }
      } catch (error) {
        console.error('删除商品失败:', error);
        let errorMsg = '删除失败';
        if (error.response) {
          switch (error.response.status) {
            case 404:
              errorMsg = '接口不存在，请检查网络连接';
              break;
            case 500:
              errorMsg = '服务器错误，请稍后重试';
              break;
            default:
              errorMsg = error.response.data?.message || errorMsg;
          }
        } else if (error.request) {
          errorMsg = '网络请求未响应，请检查网络连接';
        } else {
          errorMsg = error.message || errorMsg;
        }

        alert(errorMsg);
      } finally {
        this.showDeleteConfirm = false;
        this.productToDelete = null;
      }
    },
    async saveProduct() {
      if (!this.currentProduct.name || !this.currentProduct.pointsPrice || !this.currentProduct.stock) {
        alert('请填写完整信息');
        return;
      }

      this.isSaving = true;

      try {
        this.currentProduct.images = JSON.stringify(this.uploadedImageUrls);

        let response;
        if (this.isEditing) {
          response = await axios.put('/api/mallProducts/update', this.currentProduct);
        } else {
          response = await axios.post('/api/mallProducts/add', this.currentProduct);
        }

        if (response.code === 200) {
          alert(this.isEditing ? '商品更新成功' : '商品添加成功');
          this.closeDialog();
          this.loadProducts();
        } else {
          alert('操作失败: ' + response.msg);
        }
      } catch (error) {
        console.error('保存商品失败:', error);
        alert('操作失败');
      } finally {
        this.isSaving = false;
      }
    },
    prevPage() {
      if (this.currentPage > 1) {
        this.currentPage--;
        this.loadProducts();
      }
    },
    nextPage() {
      if (this.currentPage < this.totalPages) {
        this.currentPage++;
        this.loadProducts();
      }
    }
  }
};
</script>

<style scoped>
.products-admin {
  padding: 20px;
  background: #f8f9fa;
  min-height: 100vh;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

.content {
  max-width: 1200px;
  margin: 0 auto;
}

.content-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  background: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

.content-header h2 {
  margin: 0;
  color: #333;
  font-size: 20px;
  font-weight: 600;
}

.add-btn {
  background: #28a745;
  color: white;
  border: none;
  padding: 10px 16px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
}

.add-btn:hover {
  background: #218838;
}

.filter-section {
  background: white;
  padding: 15px;
  margin-bottom: 20px;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

.filter-group {
  display: flex;
  gap: 10px;
  align-items: center;
}

.search-input {
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  flex: 1;
}

.filter-select, .category-select {
  width: 200px;
  height: 40px;
  padding: 8px 12px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  background-color: white;
  font-size: 14px;
  color: #606266;
}

.filter-select:focus, .category-select:focus {
  border-color: #409eff;
  outline: none;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

.search-btn {
  padding: 8px 16px;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.search-btn:hover {
  background: #0056b3;
}

.table-container {
  background: white;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
  overflow-x: auto;
}

.products-table {
  width: 100%;
  border-collapse: collapse;
}

.products-table th {
  background: #f8f9fa;
  padding: 16px 12px;
  text-align: left;
  font-weight: 600;
  color: #555;
  border-bottom: 2px solid #e0e0e0;
  font-size: 14px;
}

.products-table td {
  padding: 16px 12px;
  border-bottom: 1px solid #e0e0e0;
  color: #333;
  font-size: 14px;
}

.products-table tr:hover {
  background: #f8f9fa;
}

.product-image {
  width: 40px;
  height: 40px;
  background: #f0f0f0;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.product-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.image-placeholder {
  font-size: 20px;
}

.status {
  padding: 4px 8px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 500;
}

.status-on {
  background: #d4edda;
  color: #155724;
}

.status-off {
  background: #f8d7da;
  color: #721c24;
}

.action-buttons {
  display: flex;
  gap: 8px;
}

.btn-edit, .btn-on, .btn-off, .btn-delete {
  padding: 6px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 500;
  transition: all 0.2s;
}

.btn-edit {
  background: #fff3cd;
  color: #856404;
  border-color: #ffeaa7;
}

.btn-edit:hover {
  background: #ffeaa7;
}

.btn-on {
  background: #d4edda;
  color: #155724;
  border-color: #c3e6cb;
}

.btn-on:hover {
  background: #c3e6cb;
}

.btn-off {
  background: #f8d7da;
  color: #721c24;
  border-color: #f5c6cb;
}

.btn-off:hover {
  background: #f5c6cb;
}

.btn-delete {
  background: #f8d7da;
  color: #721c24;
  border-color: #f5c6cb;
}

.btn-delete:hover {
  background: #f5c6cb;
}

.pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 15px;
  margin-top: 20px;
  padding: 15px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

.pagination button {
  padding: 8px 16px;
  border: 1px solid #ddd;
  background: white;
  border-radius: 4px;
  cursor: pointer;
}

.pagination button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.pagination button:hover:not(:disabled) {
  background: #f0f0f0;
}

.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
  padding: 20px;
}

.modal {
  background: white;
  border-radius: 12px;
  max-width: 500px;
  width: 90%;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
  overflow: hidden;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 20px 0 20px;
  border-bottom: 1px solid #eee;
}

.modal-header h3 {
  margin: 0;
  color: #333;
  font-size: 1.4rem;
  font-weight: 600;
}

.close-btn {
  background: none;
  border: none;
  font-size: 24px;
  cursor: pointer;
  color: #999;
}

.close-btn:hover {
  color: #333;
}

.modal-content {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  max-height: calc(80vh - 120px);
}

.modal-footer {
  padding: 20px;
  border-top: 1px solid #eee;
  display: flex;
  justify-content: flex-end;
  gap: 15px;
  background: white;
}

.form-group {
  margin-bottom: 15px;
}

.form-group label {
  display: block;
  margin-bottom: 5px;
  font-weight: 500;
  color: #333;
}

.form-group input,
.form-group select,
.form-group textarea {
  width: 100%;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
}

.form-group textarea {
  height: 80px;
  resize: vertical;
}

.btn-cancel, .btn-confirm {
  padding: 10px 20px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-weight: 500;
  font-size: 14px;
  transition: all 0.3s;
}

.btn-cancel {
  background-color: #ddd;
  color: #333;
}

.btn-cancel:hover {
  background-color: #ccc;
}

.btn-confirm {
  background-color: #28a745;
  color: white;
}

.btn-confirm:hover {
  background-color: #218838;
}

.btn-confirm:disabled {
  background-color: #ccc;
  cursor: not-allowed;
}

.uploaded-images {
  display: flex;
  gap: 10px;
  margin-top: 10px;
  flex-wrap: wrap;
}

.image-preview {
  position: relative;
  width: 100px;
  height: 100px;
  border: 1px solid #ddd;
  border-radius: 4px;
  overflow: hidden;
}

.image-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.remove-image-btn {
  position: absolute;
  top: 2px;
  right: 2px;
  background: #ff4444;
  color: white;
  border: none;
  border-radius: 50%;
  width: 20px;
  height: 20px;
  cursor: pointer;
  font-size: 12px;
  line-height: 1;
}

.upload-progress {
  margin-top: 10px;
  height: 20px;
  background: #f0f0f0;
  border-radius: 4px;
  overflow: hidden;
  position: relative;
}

.progress-bar {
  height: 100%;
  background: #007bff;
  transition: width 0.3s;
}

.upload-progress span {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  text-align: center;
  line-height: 20px;
  color: white;
  font-size: 12px;
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 15px;
  margin-top: 25px;
  padding: 0 20px 20px;
}

@media (max-height: 600px) {
  .modal {
    max-height: 90vh;
  }

  .modal-content {
    max-height: 70vh;
  }
}
</style>